package me.crawler;

import java.net.*;
import java.util.*;

public class URLQueue {
	
	
	Queue  <URL> evenQueue;
	Queue  <URL> oddQueue;
	Set <URL> retrievedLinks;
	Set <URL> processedLinks;

	/**
	 * Maximum number of elements allowed in the gatheredLinks set
	 */
	int maxLinks;
	int maxDepth;



	public URLQueue() {
		evenQueue = new LinkedList();
		oddQueue = new LinkedList();
		retrievedLinks = new  HashSet();
		processedLinks = new HashSet();
		maxLinks = -1;
		maxDepth = -1;
		
	}


	public void setMaxLinks(int _maxLinks) {
		maxLinks = _maxLinks;
	}


	public Set getGatheredElements() {
		return retrievedLinks;
	}


	public Set getProcessedLinks() {
		return processedLinks;
	}


	public int getQueueSize(int level) {
		if (level % 2 == 0) {
			return evenQueue.size();
		} else {
			return oddQueue.size();
		}
	}


	public int getProcessedSize() {
		return processedLinks.size();
	}


	public int getGatheredSize() {
		return retrievedLinks.size();
	}
	
	public int size(){		
		return evenQueue.size() + oddQueue.size();	
	}


	public synchronized URL pop(int level) {
		URL url;

		if (level % 2 == 0) 
			if (evenQueue.size() == 0) 
				return null;
			else 
				url =  evenQueue.remove();
			
		else 
			if (oddQueue.size() == 0) 
				return null;
			else 
				url =  oddQueue.remove();	
		
		processedLinks.add(url);
		
		return  url;
	}


	public synchronized boolean push(URL url, int level) {
		
		if (maxLinks != -1 && maxLinks <= retrievedLinks.size() || maxDepth != -1 && maxDepth > level)
			return false;
		
		if (retrievedLinks.add(url)){ 
			if (level % 2 == 0) 
				evenQueue.add(url);
			 else 
				oddQueue.add(url);
			
			return true;
		}
		 else 
			return false;
		
	}
	
	public synchronized boolean isEmpty(){
		
		if (oddQueue.isEmpty() && evenQueue.isEmpty())
			return true;
		else
			return false;		
	} 
	
	public synchronized boolean full(){
		
		if(retrievedLinks.size()>= maxLinks)
			return true;
		else 
			return false;
	} 

	public synchronized void clear() {
		evenQueue.clear();
		oddQueue.clear();
	}
	
}
